#include <iostream>
#include <memory>
#include <vector>
#include "err.hpp"
#include "http_server.hpp"
#include "util.hpp"

using namespace std;
const string web_root = "./web_root"; //网站根目录
const string home_page = "/index.html"; //网站主页
string page_404 = "./web_root/page_404.html";
const string SEP  = "\r\n";

class http_request
{
public:
    http_request():_path(web_root){}
    void Print()
    {
        cout << "method: " << _method << endl;
        cout << "url: " << _url << endl;
        cout << "version: " << _version << endl;
        // cout << "body:" << endl;
        // for(auto &it : _body)
        // {
        //     cout << "    " << it << endl;
        // }
        cout << "path: " << _path << endl;
        cout << "suffix: " << _suffix << endl;
    }
public:
    // GET http://www.baidu.com HTTP/1.1\r\n
    // Header...(请求的属性，冒号分割的键值对，每组属性之间用\r\n分割)
    // \r\n
    // Body

    string _method;
    string _url;
    string _version;
    vector<string> _body;
    string _path;
    string _suffix;
};

// 反序列化
http_request deserialize(string &msg)
{
    http_request request;
    string line = util::read_one_line(msg, SEP);
    util::parse_first_line(line, request._method, request._url, request._version);

    while(!msg.empty())
    {
        line = util::read_one_line(msg, SEP);
        request._body.push_back(line);
    }

    if(request._url == "/" || request._url.empty())
        request._path += home_page;
    else
        request._path += request._url;

    // 后缀
    size_t pos = request._path.rfind(".");
    if(pos == string::npos)
        request._path += ".html";
    else
        request._suffix = request._path.substr(pos);
    
    return request;
}

string get_content_type(const string &suffix)
{
    // HTTP Content-type 对照表
    string content_type = "Content-Type: ";

    if(suffix == ".html") content_type += "text/html";
    else if(suffix == ".jpg" || suffix == ".jpeg") content_type += "image/jpeg";
    else if(suffix == ".png") content_type += "image/png";
    else if(suffix == ".mp4") content_type += "video/mpeg4";

    // content_type += SEP;
    return content_type;
}

// 返回的是http response
string handler_http(string &request)
{
    // 1.读取请求，确认request是一个完整的http请求报文
    // cout << "request: " << request << endl;

    if(request.empty())
    {
        string file;
        string response;
        response += "HTTP/1.1 404 Not Found" + SEP;
        util::read_file(page_404, file);
        response += "Content-Lenght: " + to_string(file.size()) + SEP;
        response += "Content-Type: text/html" + SEP;
        response += SEP;
        response += file;
        return response;
    }

    // 2.反序列化和分析请求
    // 图片(.png .jpg), 网页(.html), 视频(.mp4)等都有自己的后缀
    http_request req = deserialize(request);
    req.Print();

    // 3.获取服务器资源（网站资源）
    string file;
    string response;
    if(util::read_file(req._path, file) == true)
    {
        // http响应报文
        // 协议版本 状态码 状态码描述\r\n
        // key:value...\r\n
        // \r\n
        // 有效载荷
        response += "HTTP/1.1 200 OK" + SEP;
        response += "Content-Lenght: " + to_string(file.size()) + SEP;
        response += get_content_type(req._suffix) + SEP;
        response += SEP;
        response += file;
    }
    else
    {
        response += "HTTP/1.1 404 Not Found" + SEP;
        util::read_file(page_404, file);
        response += "Content-Lenght: " + to_string(file.size()) + SEP;
        response += get_content_type(req._suffix) + SEP;
        response += SEP;
        response += file;
    }
    
    cout << "--------------------------------------------" << endl;
    return response;
}

int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        cout << "参数个数错误" << endl;
        exit(USAGE_ERR);
    }
    uint16_t port = atoi(argv[1]);
    unique_ptr<http_server> hs(new http_server(handler_http, port));
    hs->init();
    hs->start();

    return 0;
}